package emd24.telstudyresources;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;

import android.os.AsyncTask;
import android.os.StrictMode;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.NumberPicker;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;

public class QuizCreatorActivity extends Activity {

	private Quiz quiz;
	private ArrayList<BankHeader> head = new ArrayList<BankHeader>();
	private TimerDialog timeDialog = null;
	private int mHour;
	private int mMinute;
	private int index;
	private TextView displayTime;
	private EditText numberText;
	private Spinner topicList;

	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
		StrictMode.setThreadPolicy(policy); 
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_quiz_creator);	

		// Create the header for the quizzes
		Bundle b = this.getIntent().getExtras();
		setTitle("Custom Quiz");
		this.head = b.getParcelableArrayList("header");

		this.displayTime = (TextView) this.findViewById(R.id.view_time);
		this.numberText = (EditText) this.findViewById(R.id.num_Questions);
		
		mMinute = head.get(0).getDefaultTime() % 60;
		mHour = head.get(0).getDefaultTime() / 60;


		this.displayTime.setText(((mHour < 10) ? "0" : "")+ mHour + ":" + 
				((mMinute < 10) ? "0" : "") +  mMinute);



		// Set the spinner
		String[] names = new String[this.head.size()];
		for(int i = 0; i < this.head.size(); i++){
			names[i] = this.head.get(i).getName();
		}
		this.topicList = (Spinner) this.findViewById(R.id.spin_topic);
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
				android.R.layout.simple_spinner_item, names);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		this.topicList.setAdapter(adapter);	
		this.topicList.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View arg1,
					int pos, long id) {
				index = pos;
				
				// Update the default time in the timer
				mMinute = head.get(pos).getDefaultTime() % 60;
				mHour = head.get(pos).getDefaultTime() / 60;
				displayTime.setText(((mHour < 10) ? "0" : "")+ mHour + ":" + 
						((mMinute < 10) ? "0" : "") +  mMinute);
				numberText.setText("" + 5);

			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				index = -1;

			}
		});

		// Set click listeners
		this.findViewById(R.id.btn_setTime).setOnClickListener(new OnClickListener() {
			public void onClick(View v){
				displayTimerDialog("Set Time Limit");
			}
		});


		this.findViewById(R.id.btnBegQuiz).setOnClickListener(new OnClickListener() {
			public void onClick(View v){
				if (mHour == 0 && mMinute == 0) {
					inputError("That's an invalid time!");
				}else if(numberText.getText().toString().equals("")){
					inputError("Must enter number of questions!");
				}
				else { 
					begQuiz();
				}
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_quiz_creator, menu);
		return true;
	}
	/**
	 * Creates a quiz from a JSON file and starts the quiz. 
	 * 
	 */
	private void begQuiz(){
		Intent i = new Intent(this,QuestionActivity.class);
		Quiz q = null;
		if(this.index == -1){
			forceUserPickTopic();
			return;
		}
		// Import Quiz as a JSON file
		int number = Integer.parseInt(this.numberText.getText().toString());
		if(!validateNumQuestions(number, this.head.get(this.index).getNumQuestions())){
			return;
		}
		QuizLoader ld = new QuizLoader(number);
		ld.execute(this.head.get(this.index).getUrl());
		try {
			q = ld.get();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		// If the quiz was not properly created
		if(q == null){
			badQuiz();
			return;
		}
		i.putExtra("quiz", q);
		i.putExtra("mark",false);
		i.putExtra("study", false);
		i.putExtra("qIndex", 0);
		i.putExtra("time",(this.mHour * 3600 + this.mMinute * 60) * 1000L);
		startActivity(i);
		finish();
	}
	/**
	 * Displays a dialog box for an error when the
	 * quiz is being created.
	 * 
	 */
	private void badQuiz(){
		new AlertDialog.Builder(this).setMessage(R.string.bad_quiz).
		setNeutralButton("Ok", new DialogInterface.OnClickListener() {

			// Set listener for when yes button is clicked, exit activity
			public void onClick(DialogInterface arg0, int arg1) {

			}
		}).show();
	}

	/**
	 * Asynchronusly creates a Quiz from a JSON file
	 * stored at a given URL
	 * 
	 * @authors Evan Dyke, William Easton
	 *
	 */
	public class QuizLoader extends AsyncTask<String, Void, Quiz>{

		ProgressDialog d;
		int numQuestions;

		protected QuizLoader(int numQuestions){
			super();
			this.numQuestions = numQuestions;
		}

		protected void onPreExecute() {
			super.onPreExecute();
			d = new ProgressDialog(QuizCreatorActivity.this);
			d.setMessage("Loading Quiz");
			d.setIndeterminate(false);
			d.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			d.setCancelable(true);
			d.show();
		}
		protected Quiz doInBackground(String... params) {
			String parsedResult = null;
			try {
				// Get the JSON from online
				Log.e("QuizLoader"," QuizLoader: Starting Parse");
				URL url = new URL(params[0]);
				Log.e("QuizLoader"," QuizLoader: Starting Connection");
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				conn.setDoInput(true);
				Log.e("QuizLoader"," QuizLoader:  Opening Connection");
				conn.connect(); //Open connection, code will fail here if there is no network connection
				InputStream is = conn.getInputStream();
				Log.e("QuizLoader"," QuizLoader:  Closing Connection");
				parsedResult = getStringFromInputStream(is);	
				Log.e("QuizLoader: Parsed", "QuizLoader " + parsedResult);
				Log.e("QuizLoader: Parsed", "QuizLoader " + parsedResult);
				is.close();

				// Create the quiz
				return new Quiz(new JSONObject(parsedResult), this.numQuestions, true);
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			}
			return null;
		}
		protected void onPostExecute(Quiz q){
			d.dismiss();
		}
	}
	private static String getStringFromInputStream(InputStream is) {

		BufferedReader br = null;
		StringBuilder sb = new StringBuilder();

		String line;
		try {
			br = new BufferedReader(new InputStreamReader(is));
			while ((line = br.readLine()) != null) {
				sb.append(line);
			}

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return sb.toString();
	}
	/**
	 * Displays a timer dialog for the user to set the time
	 * 
	 * @param title title for the dialog
	 */
	private void displayTimerDialog(String title){
		new TimerDialog(this, new TimePickerDialog.OnTimeSetListener() {

			@Override
			public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
				mHour = hourOfDay;
				mMinute = minute;
				displayTime.setText(((hourOfDay < 10) ? "0" : "")+ hourOfDay + ":" 
						+ ((minute < 10) ? "0" : "") +  minute);
			}

		},this.mHour, this.mMinute, true, title).show();
	}
	private void inputError(String msg) {
		new AlertDialog.Builder(this).setMessage(msg).
		setNeutralButton("Retry", new DialogInterface.OnClickListener() {
			// Set listener for when yes button is clicked, exit activity
			public void onClick(DialogInterface arg0, int arg1) {

			}
		}).show();
	}
	private void forceUserPickTopic() {
		new AlertDialog.Builder(this).setMessage("Must choose a topic!").
		setNeutralButton("Retry", new DialogInterface.OnClickListener() {
			// Set listener for when yes button is clicked, exit activity
			public void onClick(DialogInterface arg0, int arg1) {

			}
		}).show();
	}
	/**
	 * Checks to see if the user entered the correct number of questions.
	 * 
	 * @param num number of questions
	 * @return boolean whether valid
	 */
	private boolean validateNumQuestions(int num, int maxQuestions) {
		if (num == 0){
			new AlertDialog.Builder(this).setMessage("Cannot enter zero questions!").
			setNeutralButton("Retry", new DialogInterface.OnClickListener() {
				// Set listener for when yes button is clicked, exit activity
				public void onClick(DialogInterface arg0, int arg1) {

				}
			}).show();
			return false;
		}else if (num > maxQuestions){
			new AlertDialog.Builder(this).setMessage("Maxmimum quiz length of " + maxQuestions +
					" questions!").
					setNeutralButton("Retry", new DialogInterface.OnClickListener() {
						// Set listener for when yes button is clicked, exit activity
						public void onClick(DialogInterface arg0, int arg1) {

						}
					}).show();
			return false;
		}else{
			return true;
		}
	}
}
